package com.second.app.excutor;

import java.util.concurrent.*;

/**
 * @Author GYZ
 * @Date 2024/2/1
 * <pre>
 *  队列
 *  线程池的几种拒绝策略
 * </pre>
 */
public class ThreadExecutor1API {

    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = () -> {
            try {
                Thread.sleep(1000);
                System.out.println("打印了！" + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2,
                5, TimeUnit.SECONDS, new LinkedBlockingDeque<>());

        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        Thread.sleep(1000);
        System.out.println(executor.getCompletedTaskCount());
        Thread.sleep(1000);
        System.out.println(executor.getCompletedTaskCount());
        Thread.sleep(1000);
        System.out.println(executor.getCompletedTaskCount());
        Thread.sleep(1000);
        System.out.println(executor.getCompletedTaskCount());
        Thread.sleep(1000);
        System.out.println(executor.getCompletedTaskCount());
    }
}
//常见3种队列结合Max值的因果效果，执行的任务数量在大于ThreadExecutor线程池的最大size时，在不同的队列会出现什么样的情况

class LinkedBlockingQueue {
    public static void main(String[] args) {
        BlockingDeque<Runnable> blockingDeque = new LinkedBlockingDeque<>(2);
        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 3, 5,
                TimeUnit.SECONDS, blockingDeque);
        Runnable runnable = () -> {
            System.out.println("begin " + System.currentTimeMillis());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(" end " + System.currentTimeMillis());
        };
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        System.out.println(executor.getPoolSize() + " " + blockingDeque.size());
    }
    //从执行结果看，放入队列2个任务，执行3个任务
}

class LinkedBlocking1Queue {
    public static void main(String[] args) {
        BlockingDeque<Runnable> blockingDeque = new LinkedBlockingDeque<>(2);
        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 3, 5,
                TimeUnit.SECONDS, blockingDeque);
        Runnable runnable = () -> {
            System.out.println("begin " + System.currentTimeMillis());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(" end " + System.currentTimeMillis());
        };
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        System.out.println(executor.getPoolSize() + " " + blockingDeque.size());
    }
    //从执行结果看，其中一个任务被拒绝执行，其他任务正常执行。
}

class SynchronousQueueTest {
    public static void main(String[] args) {
        SynchronousQueue<Runnable> synchronousQueue = new SynchronousQueue<>();
        System.out.println(synchronousQueue.size());
        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 3, 5,
                TimeUnit.SECONDS, synchronousQueue);
        Runnable runnable = () -> {
            System.out.println("begin " + System.currentTimeMillis());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(" end " + System.currentTimeMillis());
        };
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        System.out.println(executor.getPoolSize() + " " + synchronousQueue.size());
    }
}

class SynchronousQueue1Test {
    public static void main(String[] args) {
        SynchronousQueue<Runnable> synchronousQueue = new SynchronousQueue<>();
        System.out.println(synchronousQueue.size());
        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 3, 5,
                TimeUnit.SECONDS, synchronousQueue);
        Runnable runnable = () -> {
            System.out.println("begin " + System.currentTimeMillis());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(" end " + System.currentTimeMillis());
        };
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        System.out.println(executor.getPoolSize() + " " + synchronousQueue.size());
    }
    //从运行结果来看，有3个任务正常执行，另外一个任务被拒绝执行，因为线程数已经超过max值了
}
//AbortPolicy：使用AbortPolicy策略后，线程数量超出Max值时，线程池抛出java.util.concurrent.rejectedExecutionException

class AbortPolicyTest {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 3, 5,
                TimeUnit.SECONDS, new ArrayBlockingQueue<>(2), new ThreadPoolExecutor.AbortPolicy());

        Runnable runnable = () -> {
            System.out.println(Thread.currentThread().getName() + " 执行任务 ");
        };
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);

        executor.execute(runnable);
    }
}

//最大线程数3个，队列最大容量2个，根据结果可得知，线程main被阻塞，严重影响程序的运行效率，所以并不建议这样做
//使用callerRunsPolicy数据不会丢失，当线程池的最大线程数到达并且阻塞队列已满的情况下
//如果使用CallerRunsPolicy
class CallerRunsPolicy {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 3, 5,
                TimeUnit.SECONDS, new LinkedBlockingDeque<>(2), new ThreadPoolExecutor.CallerRunsPolicy());

        Runnable runnable = () -> {
            System.out.println(Thread.currentThread().getName() + " 执行任务 ");
        };
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
    }
}

//afterExecute和beforeExecute
class CustomThreadPoolExecutor extends ThreadPoolExecutor {

    public CustomThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
                                    TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        System.out.println("执行完了！！！！！！！！！");
    }

    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        super.beforeExecute(t, r);
        System.out.println("开始执行！！！！！");
    }
}

class RunThreadExecutor {
    public static void main(String[] args) {

        Runnable runnable = () -> {
            System.out.println(Thread.currentThread().getName() + "执行任务");
        };
        CustomThreadPoolExecutor customThreadPoolExecutor = new CustomThreadPoolExecutor(2, 2,
                Integer.MAX_VALUE, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
        customThreadPoolExecutor.execute(runnable);
        customThreadPoolExecutor.execute(runnable);
        customThreadPoolExecutor.execute(runnable);
        customThreadPoolExecutor.execute(runnable);
    }
}